package com.wcl.hencodertest.test15_drag_nestedscroll.drag;

import android.content.Context;
import android.os.Build;
import android.util.AttributeSet;
import android.view.DragEvent;
import android.view.View;
import android.view.ViewGroup;

import androidx.annotation.RequiresApi;

import java.util.ArrayList;
import java.util.List;

public class DragListenerGridView extends ViewGroup {
    /**
     * 列数
     */
    public static final int COLUMNS = 2;
    /**
     * 行数
     */
    public static final int ROWS = 3;
    private final MyDragListener dragListener;

    private List<View> orderedChildViews = new ArrayList<>();
    private View currentDraggingView;

    public DragListenerGridView(Context context, AttributeSet attrs) {
        super(context, attrs);
        setChildrenDrawingOrderEnabled(true);
        dragListener = new MyDragListener();
    }

    @Override
    protected void onFinishInflate() {
        super.onFinishInflate();
        for (int i = 0; i < getChildCount(); i++) {
            View childView = getChildAt(i);
            orderedChildViews.add(childView);
            childView.setOnLongClickListener(new OnLongClickListener() {
                @RequiresApi(api = Build.VERSION_CODES.N)
                @Override
                public boolean onLongClick(View v) {
                    currentDraggingView = v;
                    v.startDragAndDrop(null, new DragShadowBuilder(v), v, 0);
                    return false;
                }
            });
            childView.setOnDragListener(dragListener);
        }
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        int width = MeasureSpec.getSize(widthMeasureSpec);
        int height = MeasureSpec.getSize(heightMeasureSpec);
        int childWidth = width / COLUMNS;
        int childHeight = height / ROWS;
        measureChildren(MeasureSpec.makeMeasureSpec(childWidth, MeasureSpec.EXACTLY),
                MeasureSpec.makeMeasureSpec(childHeight, MeasureSpec.EXACTLY));
        setMeasuredDimension(width, height);
    }

    @Override
    protected void onLayout(boolean changed, int l, int t, int r, int b) {
//        int childWidth = getWidth() / COLUMNS;
//        int childHeight = getHeight() / ROWS;
//        for (int i = 0; i < getChildCount(); i++) {
//            View child = getChildAt(i);
//            int left;
//            if (i % 2 == 0) {
//                left = 0;
//            } else {
//                left = childWidth;
//            }
//            int top = i / 2 * childHeight;
//            child.layout(left, top, left + childWidth, top + childHeight);
//        }
        int count = getChildCount();
        int childLeft;
        int childTop;
        int childWidth = getWidth() / COLUMNS;
        int childHeight = getHeight() / ROWS;
        for (int index = 0; index < count; index++) {
            View child = getChildAt(index);
            childLeft = index % 2 * childWidth;
            childTop = index / 2 * childHeight;
            child.layout(0, 0, childWidth, childHeight);
            child.setTranslationX(childLeft);
            child.setTranslationY(childTop);
        }
    }

    class MyDragListener implements OnDragListener {

        @Override
        public boolean onDrag(View v, DragEvent event) {
            switch (event.getAction()) {
                case DragEvent.ACTION_DRAG_STARTED:
                    if (event.getLocalState() == v) {
                        v.setVisibility(INVISIBLE);
                    }
                    break;
                case DragEvent.ACTION_DRAG_ENTERED:
                    if (event.getLocalState() != v) {
                        sort(v);
                    }
                    break;
                case DragEvent.ACTION_DRAG_EXITED:
                    break;
                case DragEvent.ACTION_DRAG_ENDED:
                    if (event.getLocalState() == v) {
                        v.setVisibility(VISIBLE);
                    }
                    break;
            }
            return true;
        }
    }

    private void sort(View targetView) {
        int targetIndex = -1;
        int draggingIndex = -1;
        for (int i = 0; i < getChildCount(); i++) {
            View child = orderedChildViews.get(i);
            if (targetView == child) {
                targetIndex = i;
            } else if (child == currentDraggingView) {
                draggingIndex = i;
            }
        }
        if (targetIndex != -1 && draggingIndex != -1 ) {
            orderedChildViews.remove(draggingIndex);
            orderedChildViews.add(targetIndex, currentDraggingView);
        }

        int childWidth = getWidth() / COLUMNS;
        int childHeight = getHeight() / ROWS;
        for (int i = 0; i < orderedChildViews.size(); i++) {
            View child = orderedChildViews.get(i);
            int left = i % 2 * childWidth;
            int top = i / 2 * childHeight;
            child.animate()
                    .translationX(left)
                    .translationY(top);
        }

    }
}
